package com.sinux.sshUser.realm;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.sinux.sshUser.entity.Permission;
import com.sinux.sshUser.entity.Role;
import com.sinux.sshUser.entity.User;
import com.sinux.sshUser.service.UserServiceI;


/** 自定义登录realm
 * @author WangGan
 * @version 2017年6月7日 下午4:22:04
 * 
 */

public class loginRealm extends AuthorizingRealm {

	@Autowired
	private UserServiceI userService;
	public static final String SESSION_USER_KEY = "user";
	
	//授权方法
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 获取当前的用户名
		//String logname=(String)getAvailablePrincipal(principals);
		//根据用户名查找对象
		//获取session中的User对象   注意：该 session 并不是 客户端 session，而是 Shiro 的session
		User user = (User) SecurityUtils.getSubject().getSession().getAttribute(loginRealm.SESSION_USER_KEY);
		//User user=userService.findByLogName(logname);
		if(user!=null){
			SimpleAuthorizationInfo  info=new SimpleAuthorizationInfo();
			Set<Role> roles=user.getRoles();
			Set<String> ronames=new HashSet<String>();
			Set<String> pernames=new HashSet<String>();
			//根据用户名查找用户对象,根据用户对象查找角色,根据角色查找权限
			for(Role role:roles){
				ronames.add(role.getRoname());
				Set<Permission> permits=role.getPermits();
				for(Permission permit:permits){
					pernames.add(permit.getPername());
				}
			}
			
			//添加角色(Set<String>)
			info.setRoles(ronames);
			//添加权限(Set<String>)
			info.setStringPermissions(pernames);
			return info ;
		}
		
		
		return null;
	}
	
	//认证方法
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
		// 把 token 转成 user
		User userinfo = tokenToUser((UsernamePasswordToken) authToken);
		// 验证用户是否可以登录
		User user = userService.login(userinfo);
		if (user != null) {
			Session session = SecurityUtils.getSubject().getSession();
			session.setAttribute(loginRealm.SESSION_USER_KEY, user);
			// 当前 Realm 的 name
			String realmName = this.getName();
			
			//身份，即主体的标识属性，可以是任何东西，这里是根据 token 的 username 查询得到的
			Object principal = authToken.getPrincipal();
			//证明/凭证，即只有主体知道的安全值，如密码/数字证书等
			Object credentials=authToken.getCredentials();
			SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials, realmName);
			return info;
		}
		// 设置 session
		return null;
	}

	private User tokenToUser(UsernamePasswordToken authToken) {
		User user = new User();
		String logname = authToken.getUsername();
		//密码在创建token时已经过MD5加密
		String pwd =String.valueOf(authToken.getPassword());
		user.setLogname(logname);
		user.setPwd(pwd);
		return user;
	}

}
